package net.hn.hnms.biz.safety.fire.Service;

import lombok.RequiredArgsConstructor;
import net.hn.hnms.biz.api.feign.model.DataStateVo;
import net.hn.hnms.biz.safety.fire.Dao.ODSSensorMonitorDao;
import net.hn.hnms.biz.safety.fire.entity.ODSSensorMonitor;
import net.hn.hnms.biz.safety.fire.entity.ODSSensorMonitorVo;
import net.hn.hnms.biz.safety.fire.unit.BaseMap;
import net.hn.hnms.sys.common.core.domain.ResponsePage;
import net.hn.hnms.sys.common.mybatis.core.page.PageQuery;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author 智呈物联 nzw
 * @date 2022/8/1
 */
@Service
@RequiredArgsConstructor
public class ODSSensorMonitorService {
    private final JdbcTemplate locationJdbcTemplate;

    @Autowired
    ODSSensorMonitorDao sensorMonitorDao;
    //通用处理方法
    //判断测点异常状态
    private void sensorMap(Map<String,Object> map){
        String state = map.get("state")+"";
        if (!state.contains("no")){
            String[] states = state.split("\\|");
            map.put("state",states);
        }else {
            String[] states  = new String[]{"no"};
            map.put("state",states);
        }
    }

    public Boolean tableState(){
        Integer countDwsNow = sensorMonitorDao.countDwsNow();
        Integer countDwdNow = sensorMonitorDao.countDwdNow();

        if (countDwsNow==0){
            if (countDwdNow==0){
                return true;
            }else {
                return false;
            }
        }else {
            return true;
        }
    }



    public List<Map<String,Object>> findAll(String samplingLocation, Date start,Date end,String mineCode){
        List<Map<String,Object>> maps = new ArrayList<>();

        //时间处理，未指定时间默认查询30天内数据
        if (end==null){
            end = new Date();
        }
        if (start==null){
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(end);
            calendar.add(Calendar.MONTH,-1);
            start = calendar.getTime();
        }
        List<ODSSensorMonitor> list= new ArrayList<>();
        if ("".equals(samplingLocation)&&samplingLocation!=null){
            list = sensorMonitorDao.historyBySamplingLocation(samplingLocation,mineCode,start,end);
        }else {
            list = sensorMonitorDao.historyByTime(mineCode,start,end);
        }

        for (ODSSensorMonitor odsSensorMonitor:list){
            Map<String,Object> map = BaseMap.entityToMap(odsSensorMonitor);
            sensorMap(map);
            maps.add(map);
        }

        return maps;
    }

    public ResponsePage<ODSSensorMonitorVo> pageList(PageQuery pageQuery, Date start, Date end,String mineCode){

        //时间处理，未指定时间默认查询30天内数据
        if (end==null){
            end = new Date();
        }
        if (start==null){
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(end);
            calendar.add(Calendar.MONTH,-1);
            start = calendar.getTime();
        }
        Integer pageSize = pageQuery.getPageSize();
        Integer pageNum = pageQuery.getPageNum();
        if (pageSize==null){
            pageSize = 10;
        }
        if(pageNum==null||pageNum==0){
            pageNum = 1;
        }
        List<ODSSensorMonitor> odsSensorMonitorList = sensorMonitorDao.pageSize(start,end,pageSize,(pageNum-1)*pageSize);
        List<ODSSensorMonitorVo> list = toList(odsSensorMonitorList);
        Integer pageCount = sensorMonitorDao.pageCount(mineCode,start,end);
        return new ResponsePage<>(list,pageCount);
    }

    private List<ODSSensorMonitorVo> toList(List<ODSSensorMonitor> odsSensorMonitorList){
        return odsSensorMonitorList.stream().map(t->{
            ODSSensorMonitorVo odsSensorMonitorVo = new ODSSensorMonitorVo();
            odsSensorMonitorVo.setO2Value(t.getO2Value());
            odsSensorMonitorVo.setCoValue(t.getCoValue());
            odsSensorMonitorVo.setCo2Value(t.getCo2Value());
            odsSensorMonitorVo.setC2h2Value(t.getC2h2Value());
            odsSensorMonitorVo.setC2h4Value(t.getC2h4Value());
            odsSensorMonitorVo.setC2h6Value(t.getC2h6Value());
            odsSensorMonitorVo.setC3h8Value(t.getC3h8Value());
            odsSensorMonitorVo.setCh4Value(t.getCh4Value());
            odsSensorMonitorVo.setMineCode(t.getMineCode());
            odsSensorMonitorVo.setMineName(t.getMineName());
            odsSensorMonitorVo.setSamplingLocation(t.getSamplingLocation());
            odsSensorMonitorVo.setN2Value(t.getN2Value());
            odsSensorMonitorVo.setSamplingTime(t.getSamplingTime());
            odsSensorMonitorVo.setSamplingLocationCode(t.getSamplingLocationCode());
            return odsSensorMonitorVo;
        }).collect(Collectors.toList());
    }

    private ODSSensorMonitorVo toListB(List<Map<String,Object>> maps) throws ParseException {
        Map<String,Object> map = toMap(maps);
        ODSSensorMonitorVo odsSensorMonitorVo = new ODSSensorMonitorVo();
        odsSensorMonitorVo.setO2Value(map.get("o2Value")+"");
        odsSensorMonitorVo.setCoValue(map.get("coValue")+"");
        odsSensorMonitorVo.setCo2Value(map.get("co2Value")+"");
        odsSensorMonitorVo.setC2h2Value(map.get("c2h2Value")+"");
        odsSensorMonitorVo.setC2h4Value(map.get("c2h4Value")+"");
        odsSensorMonitorVo.setC2h6Value(map.get("c2h6Value")+"");
        odsSensorMonitorVo.setC3h8Value(map.get("c3h8Value")+"");
        odsSensorMonitorVo.setCh4Value(map.get("ch4Value")+"");
        odsSensorMonitorVo.setMineCode(map.get("mineCode")+"");
        odsSensorMonitorVo.setMineName("");
        odsSensorMonitorVo.setSamplingLocation(map.get("samplingLocation")+"");
        odsSensorMonitorVo.setN2Value(map.get("n2Value")+"");
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        odsSensorMonitorVo.setSamplingTime(simpleDateFormat.parse(map.get("samplingTime")+""));
        odsSensorMonitorVo.setSamplingLocationCode("");
        return odsSensorMonitorVo;

    }

    private Map<String,Object> toMap(List<Map<String,Object>> data){
        Map<String,Object> map = new HashMap<>();
        data.forEach(dataMap ->{
            map.put("mineCode",dataMap.get("mine_code"));
            map.put("samplingTime",dataMap.get("data_time"));
            map.put("samplingLocation",dataMap.get("point_monitor_location"));
            String typeName = dataMap.get("point_type_name")+"";
            map.put(typeName.toLowerCase()+"Value",dataMap.get("point_value"));
        });

        return map;
    }

    public List<Map<String,Object>> latestData(String mineCode){
        List<Map<String,Object>> maps = new ArrayList<>();
        List<ODSSensorMonitor> list = sensorMonitorDao.latestData(mineCode);
        for (ODSSensorMonitor sensorMonitor:list){
            Map<String,Object> map = BaseMap.entityToMap(sensorMonitor);
            sensorMap(map);
            maps.add(map);
        }
        return maps;
    }

    public List<Map<String,Object>> latestDataB(String mineCode){
        //获取实时表地点信息
        List<Map<String,Object>> maps = new ArrayList<>();
        List<Map<String,Object>> monitorLocations = sensorMonitorDao.findByPointMonitorLocation(mineCode);
        monitorLocations.forEach(map -> {
            String monitorLocation = map.get("point_monitor_location")+"";
            List<Map<String,Object>> data = sensorMonitorDao.latestDataB(monitorLocation,mineCode);
            maps.add(toMap(data));
        });
        return maps;
    }

    public void save(ODSSensorMonitor odsSensorMonitor){
        sensorMonitorDao.save(odsSensorMonitor);
    }

    /**
     * 获取束管最近一周的气体变化
     * @return
     */
    public List<ODSSensorMonitor> gasChange(String samplingLocation,String mindeCode){
        if(samplingLocation==null||"".equals(samplingLocation)){
            samplingLocation = "250203下工作面回风隅角采空区(埋管）";
        }else {
            samplingLocation += "下工作面回风隅角采空区(埋管）";
        }        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.WEEK_OF_YEAR,-1);
        return sensorMonitorDao.oxygenConcentration(samplingLocation,mindeCode,calendar.getTime());
    }


    public Map<String,Object> oxygenConcentration(String samplingLocation,String mindeCode){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        List<ODSSensorMonitor> list = gasChange(samplingLocation,mindeCode);

        Map<String,String> data = time();
        for(ODSSensorMonitor odsSensorMonitor:list){
            String time = simpleDateFormat.format(odsSensorMonitor.getSamplingTime());
            String o2Value = odsSensorMonitor.getO2Value();
            data.put(time,o2Value);
        }
        String[] xData = new String[data.size()];
        String[] o2Value = new String[data.size()];
        int code = 0;
        for (String time:data.keySet()){
            xData[code] = time;
            o2Value[code] = data.get(time);
            code++;
        }

        Map<String,Object> map = new HashMap<>();
        map.put("xData",xData);
        map.put("o2Value",o2Value);
        return map;

    }

    public Map<String,Object> keyGas(String samplingLocation,String mineCode){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        List<ODSSensorMonitor> list = gasChange(samplingLocation,mineCode);

        Map<String,String> data = time();
        Map<String,String> coData = time();

        for(ODSSensorMonitor odsSensorMonitor:list){
            String time = simpleDateFormat.format(odsSensorMonitor.getSamplingTime());
            String ch4Value = odsSensorMonitor.getCh4Value();
            String coValue = odsSensorMonitor.getCoValue();
            data.put(time,ch4Value);
            coData.put(time,coValue);
        }
        String[] xData = new String[data.size()];
        String[] ch4Value = new String[data.size()];
        String[] coValue = new String[data.size()];
        int code = 0;
        for (String time:data.keySet()){
            xData[code] = time;
            ch4Value[code] = data.get(time);
            coValue[code] = coData.get(time);
            code++;
        }

        Map<String,Object> map = new HashMap<>();
        map.put("xData",xData);
        map.put("ch4Value",ch4Value);
        map.put("coValue",coValue);
        return map;


    }

    private Map<String,String> time(){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");

        Map<String,String> data = new LinkedHashMap<>();

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.WEEK_OF_YEAR,-1);

        for (;calendar.getTime().before(new Date());){
            data.put(simpleDateFormat.format(calendar.getTime()),"0.0000");
            calendar.add(Calendar.DAY_OF_YEAR,1);
        }
        return data;
    }

    public ODSSensorMonitorVo findByLocation(String samplingLocation,String mineCode){
        if(samplingLocation==null||"".equals(samplingLocation)){
            samplingLocation = "250203下工作面回风隅角采空区(埋管）";
        }else {
            samplingLocation += "下工作面回风隅角采空区(埋管）";
        }
        List<ODSSensorMonitor> list = sensorMonitorDao.findByLocation(samplingLocation,mineCode);
        if (list==null||list.size()==0){
            return new ODSSensorMonitorVo();
        }
        return toList(list).get(0);
    }

    public ODSSensorMonitorVo findByLocationGaoTouYao(String samplingLocation,String mineCode){
        if(samplingLocation==null||"".equals(samplingLocation)){
            samplingLocation = "%108%";
        }else {
            samplingLocation = "%"+samplingLocation+"%";
        }
        List<ODSSensorMonitor> list = sensorMonitorDao.findByLocationGaoTouYao(samplingLocation,mineCode);
        if (list==null||list.size()==0){
            return new ODSSensorMonitorVo();
        }
        return toList(list).get(0);
    }

    public ODSSensorMonitorVo findByLocationB(String samplingLocation,String mineCode) throws ParseException {
        List<Map<String,Object>> list = sensorMonitorDao.latestDataB(samplingLocation,mineCode);
        if (list==null||list.size()==0){
            return new ODSSensorMonitorVo();
        }
        return toListB(list);
    }

    public ODSSensorMonitorVo findByLocationGaoTouYaoB(String samplingLocation,String mineCode) throws ParseException {
        if(samplingLocation==null||"".equals(samplingLocation)){
            samplingLocation = "%108采空区%";
        }else {
            samplingLocation = "%"+samplingLocation+"%";
        }
        List<Map<String,Object>> list = sensorMonitorDao.latestDataGaoTouYaoB(samplingLocation,mineCode);
        if (list==null||list.size()==0){
            return new ODSSensorMonitorVo();
        }
        return toListB(list);
    }
    public List<DataStateVo> getMaxTime(String mineCode, String companyCode){
        String sql="SELECT mine_code as mineCode,max(data_time) as maxTime  FROM dwd_sgjc_now_sensormonitor where 1=1 %s %s group by mine_code";
        if(StringUtils.isNotBlank(mineCode)){
            mineCode ="and mine_code='"+mineCode+"' ";
        }else{
            mineCode="";
        }
        if(StringUtils.isNotBlank(companyCode)&&StringUtils.isBlank(mineCode)){
            companyCode ="and company_code='"+companyCode+"' ";
        }else {
            companyCode="";
        }
        List<DataStateVo> query = locationJdbcTemplate.query(String.format(sql, mineCode, companyCode), new BeanPropertyRowMapper<>(DataStateVo.class));
        return query;
    }

    public Map<String,Object> alarms(String mineCode){
        Map<String,Object> map = new HashMap<>();
        List<Map<String,Object>> list = new ArrayList<>();
        Map<String,Object> data1 = new HashMap<>();
        Map<String,Object> data2 = new HashMap<>();
        Map<String,Object> data3 = new HashMap<>();
        Map<String,Object> data4 = new HashMap<>();
        Map<String,Object> data5 = new HashMap<>();


        data1.put("name","火灾");
        data1.put("alarmInt",sensorMonitorDao.alarms(mineCode));
        list.add(data1);
        data2.put("name","顶板");
        data2.put("alarmInt",0);
        list.add(data2);
        data3.put("name","瓦斯");
        data3.put("alarmInt",0);
        list.add(data3);
        data4.put("name","粉尘");
        data4.put("alarmInt",0);
        list.add(data4);
        data5.put("name","水害");
        data5.put("alarmInt",0);
        list.add(data5);

        map.put("content",list);
        map.put("totalElements",5);
        return map;
    }

    public Map<String,Object> gasAddress(String mineCode){

        List<Map<String,Object>> addressList = sensorMonitorDao.findAddress(mineCode);

        Map<String,Object> data = new HashMap<>();

        String pattern = "[\\u4e00-\\u9fa5]"; // 中文字符的正则表达式
        Pattern r = Pattern.compile(pattern);

        addressList.forEach(map -> {
            String address = map.get("sampling_location")+"";
            Matcher m = r.matcher(address);
            if (m.find()){
                String[] result = address.split(pattern, 2);
                String first = result[0];
                Map<String,String> secondMap = (Map<String,String>)data.get(first);
                if (secondMap==null){
                    secondMap = new HashMap<>();
                }
                secondMap.put(address,address);
                data.put(first,secondMap);
            }
        });
        return data;
    }

    public Map<String,Object> gasCurve(String samplingLocation,String mineCode,String gasType){
        gasType = gasType+"_value";

        List<Map<String,Object>> list = findByLocationAndType(samplingLocation,mineCode,gasType);

        Map<String,String> data = time();
        for(Map<String,Object> map:list){
            String time = map.get("samplingTime")+"";
            String o2Value = map.get("data")+"";
            data.put(time,o2Value);
        }
        String[] xData = new String[data.size()];
        String[] o2Value = new String[data.size()];
        int code = 0;
        for (String time:data.keySet()){
            xData[code] = time;
            o2Value[code] = data.get(time);
            code++;
        }

        Map<String,Object> map = new HashMap<>();
        map.put("xData",xData);
        map.put("dataValue",o2Value);
        return map;
    }

    public List<Map<String,Object>> findByLocationAndType(String samplingLocation,String mineCode,String gasType){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.WEEK_OF_YEAR,-1);

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String sql = "SELECT\n" +
                "\tto_char(ods.sampling_time,'yyyy-MM-dd') as samplingTime," +
                "\tods."+gasType+" as data \n" +
                "FROM\n" +
                "\tods_sgjc_his_sensormonitor ods,\n" +
                "\t( SELECT MAX ( sampling_time ) AS maxTime, sampling_location FROM ods_sgjc_his_sensormonitor GROUP BY sampling_location ) mx \n" +
                "WHERE\n" +
                "\tods.sampling_time = mx.maxTime \n" +
                "\tAND ods.sampling_location = '" +samplingLocation+"'"+
                "\tAND ods.sampling_location = mx.sampling_location\n" +
                "\tAND to_char(ods.sampling_time,'yyyy-MM-dd') >= '" +simpleDateFormat.format(calendar.getTime())+"'"+
                "\tand CASE when '"+mineCode+"' != '' then trim(mine_code) = '"+mineCode+"' else 1=1 end";
        List<Map<String,Object>> list = locationJdbcTemplate.queryForList(sql);
        if (list==null||list.size()==0){
            return new ArrayList<>();
        }
        return list;
    }

}
